<?php
namespace App\Common\Lib\Fun;

use App\Common as com;
use App\Common\Lib\VendMachine\Tissue\User\Replenish\Order\Status;

// 需要修改后才可使用
class Time
{
	/** 'today'：特定时间类型->今天 */
	// public static $specificTime_Today = 'today';
	/** 'yt_day'：特定时间类型->昨天 */
	// public static $specificTime_Yesterday = 'yt_day';
	/** 'atfer'：特定时间类型->前天 */
	// public static $specificTime_Atfer = 'atfer';
	/** 'atfer'：特定时间类型->3天前 */
	// public static $specificTime_Three = 'three';
	/** 'atfer'：特定时间类型->4天前 */
	// public static $specificTime_Four = 'four';

	//edit by siyuan
	/** 'atfer'：特定时间类型->5天前 */
	// public static $specificTime_Five = 'five';
	/** 'atfer'：特定时间类型->6天前 */
	// public static $specificTime_Six = 'six';
	/** 'atfer'：特定时间类型->7天前 */
	// public static $specificTime_Wseven = 'wseven';
	/** 'atfer'：特定时间类型->8天前 */
	// public static $specificTime_Eight = 'eight';
	/** 'atfer'：特定时间类型->9天前 */
	// public static $specificTime_Nine = 'nine';
	/** 'atfer'：特定时间类型->10天前 */
	// public static $specificTime_Wten = 'wten';


	/** 'week'：特定时间类型->本周 */
	// public static $specificTime_Week = 'week';
	/** 'ten_day'：特定时间类型->最近10天 */
	// public static $specificTime_Ten = 'ten';
	/** 'week'：特定时间类型->本周（之前） */
	// public static $specificTime_WeekBefore = 'week_before';
	/** 'week'：特定时间类型->最近7天 */
	// public static $specificTime_Seven = 'seven';
	/** 'month'：特定时间类型->本月 */
	// public static $specificTime_Month = 'month';
	/** 'month'：特定时间类型->30天*/
	// public static $specificTime_Thirty= 'thirty';
	/** 'year'：特定时间类型->今年 */
	// public static $specificTime_Year = 'year';
	/** 'all'：特定时间类型->所有 */
	// public static $specificTime_All = 'all';

	/** 一天的总秒数 **/
	public static int $daySecond = 86400;

	/**
	 * 时间差
	 * @var int
	 */
	private static ?int $assignTime = null;

	/**
	 * 取当前时间戳
	 * @param int|null $assignTime 指定时间戳 [null]清除
	 */
	public static function setTime( ?int $assignTime ) {
		self::$assignTime = $assignTime;
	}

	/**
	 * 重置时间戳
	 */
	public static function resetTime() {
		self::$assignTime = null;
	}

	/**
	 * 是否指定了时间戳
	 * @return
	 */
	public static function isSetTime():bool {
		return self::$assignTime !== null;
	}

	/**
	 * 取当前时间戳
	 * @param bool $hasTimeDiff 是否带上时间偏移
	 * @return int 当前时间（时间戳）
	 */
	public static function getTime( bool $hasTimeDiff = true ):int {
		if( $hasTimeDiff ){
			return self::$assignTime === null ? time() : self::$assignTime;
		}else{
			return time();
		}

	}

	/**
	 * 取当前时间戳(毫秒)
	 * @return float
	 */
	public static function getTimeOfMillitime(){
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$sec * 1000 + round( (float)$usec * 1000 ) );
	}

	/**
	 * 取当前时间戳(微妙)
	 * @return float
	 */
	public static function getTimeOfMicrotime(){
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$sec * 10000 + (float)$usec * 10000);
	}
	
	/**
	 * 取特定时间戳
	 * @param str $time_unit 时间（参考：$specificTime_xxx）。['today']今日 ['yt_day']昨天 ['week']本周 ['month']本月 ['year']今年 ['all']所有
	 * @param str $assigntime 指定计算的时间戳
	 * @return array 返回生成的时间戳[
	 * 		'starttime' => 0, // 开始时间戳
	 * 		'endtime' => 0, // 结束时间戳
	 * ]
	 */
	public static function DEL_getSpecificTimestamp( $time_unit, int $assign_time = null ){
		if( $assign_time === null ) $assign_time = com\Lib\Fun\Time::getTime();
		//
		if( $time_unit == self::$specificTime_Today ){
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $assign_time ) );//今日开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $assign_time ) );//今日结束时间戳
			
		}else if( $time_unit == self::$specificTime_Yesterday ){
			$specific_time = strtotime('-1 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//昨日开始时间戳-1
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//昨日结束时间戳
			
		}else if( $time_unit == self::$specificTime_Atfer ){
			$specific_time = strtotime('-2 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//前天开始时间戳-2
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//前天结束时间戳
			
		}else if( $time_unit == self::$specificTime_Three ){
		    $specific_time = strtotime('-3 day');
		    $today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//3天开始时间戳-3
		    $today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//3天结束时间戳
		    
		}else if( $time_unit == self::$specificTime_Four ){
			$specific_time = strtotime('-4 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//4前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//4前天结束时间戳
			//editby siyuan
		}else if( $time_unit == self::$specificTime_Five ){
			$specific_time = strtotime('-5 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//5前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//5前天结束时间戳
		}else if( $time_unit == self::$specificTime_Six ){
			$specific_time = strtotime('-6 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//6前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//6前天结束时间戳
		}else if( $time_unit == self::$specificTime_Wseven ){
			$specific_time = strtotime('-7 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//7前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//7前天结束时间戳
		}else if( $time_unit == self::$specificTime_Eight ){
			$specific_time = strtotime('-8 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//8前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//8前天结束时间戳
		}else if( $time_unit == self::$specificTime_Nine ){
			$specific_time = strtotime('-9 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//9前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//9前天结束时间戳
		}else if( $time_unit == self::$specificTime_Wten){
			$specific_time = strtotime('-10 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//10前天开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $specific_time ) );//10前天结束时间戳
		}


		else if( $time_unit == self::$specificTime_Week ){
			$date_w = date("w");
			$date_w--;
			if( $date_w == -1 ){
				$date_w = 6;
			}else if( $date_w == 5 ){
				$date_w = 0;
			}
			$today_start_time = (int)mktime(0, 0 , 0,date("m", $assign_time),date("d", $assign_time)-$date_w,date("Y", $assign_time));//本周开始时间戳
			$today_end_time = (int)mktime(23,59,59,date("m", $assign_time),date("d", $assign_time)-$date_w + 6,date("Y", $assign_time));//本周结束时间戳
			
		}else if( $time_unit == self::$specificTime_WeekBefore ){
			$specific_time = strtotime('-6 day');
			$today_start_time = (int)strtotime( date( 'y-m-d 0:0:0', $specific_time ) );//昨日开始时间戳
			$today_end_time = (int)strtotime( date( 'y-m-d 23:59:59', $assign_time ) );//今日结束时间戳
			
		}else if( $time_unit == self::$specificTime_Month ){
			$today_start_time = (int)mktime(0, 0 , 0,date("m", $assign_time),1,date("Y", $assign_time));//本月开始时间戳
			$today_end_time = (int)mktime(23,59,59,date("m", $assign_time),date("t", $assign_time),date("Y", $assign_time));//本月结束时间戳
			
		}else if( $time_unit == self::$specificTime_Year ){
			$today_start_time = (int)mktime(0,0,0,1,1,date("Y", $assign_time));//今年开始时间戳
			$today_end_time = (int)mktime(23,59,59,12,31,date("Y", $assign_time));//今年结束时间戳
			
		}else if( $time_unit == self::$specificTime_All ){
			$today_start_time = 0;//开始时间戳
			$today_end_time = (int)$assign_time;//结束时间戳
			
		}else if(  $time_unit == self::$specificTime_Thirty){
			$today_start_time = (int)mktime(0,0,0,date('m', strtotime("-1 month", $assign_time)),date('d', $assign_time),date('m', $assign_time));
			$today_end_time   = (int)strtotime( date( 'y-m-d 23:59:59', strtotime('-1 day', $assign_time)) );
			
		}else if(  $time_unit == self::$specificTime_Seven){
			$today_start_time = (int)strtotime( date( 'y-m-d 00:00:00', strtotime('-7 day', $assign_time)) );
			$today_end_time   = (int)strtotime( date( 'y-m-d 23:59:59', strtotime('-1 day', $assign_time)) );
			
		}else if(  $time_unit == self::$specificTime_Ten){
		    $today_start_time = (int)strtotime( date( 'y-m-d 00:00:00', strtotime('-10 day', $assign_time)) );
		    $today_end_time   = (int)strtotime( date( 'y-m-d 23:59:59', strtotime('-1 day', $assign_time)) );
		    
		}else{
			//输入无效时间戳类型的
			throw com\Lib\Err\Exception::makeOfNew( '', com\Cla\Err\Code::$sysFunParamError );
		}
		//
		return [
			'starttime' => $today_start_time,
			'endtime' => $today_end_time
		];
		/*
		if( $site == 'starttime' ){
			return (int)$today_start_time;
		}elseif( $site == 'endtime' ){
			return (int)$today_end_time;
		}else{
			throw com\Lib\Err\Exception::makeOfNew( '', com\Cla\Err\Code::$sysFunParamError );
		}
		*/
	}
	
	/**
	 * 获取指定时间戳当前开始的时间戳
	 * @param int $assigntime 指定时间戳（不输入则自动获取当前时间）
	 * @return int 生成的日代码时间戳（如：1502121600），当日的0时0分0秒
	 */
	public static function createDayTimeNo( $assigntime = NULL ){
		// ...
		$assigntime = $assigntime ?? com\Lib\Fun\Time::getTime();
		//
		return self::getSpecificTimestamp( self::$specificTime_Today, $assigntime )['starttime'];
	}
	
	/**
	 * 生成时间日代码
	 * @param int $assigntime 指定时间戳（不输入则自动获取当前时间）
	 * @return int 生成的日代码（如：160102）
	 */
	public static function createDayNo( $assigntime = NULL ){
		if(strpos($assigntime, '-')){
			return strtotime(date($assigntime));
		}
		return date( 'ymd', $assigntime ?? com\Lib\Fun\Time::getTime() );
	}
	
	/**
	 * 格式化时间戳
	 * @param string $format
	 * @param int $timestamp 时间戳
	 * @param str $default_str 时间戳不存在时的默认返回值
	 * @return str 格式化后的时间戳[默认返回"-"]
	 */
	public static function date( $format, $timestamp, $default_str = NULL ){
		if( $timestamp == 0 ){
			if( isset( $default_str ) ){
				return $default_str;
			}else{
				return '-';
			}
	
		}
		return date( $format, $timestamp );
	}
	
	/**
	 * 指定日期格式转换时间戳
	 * @author Jason
	 * 例：2018-1-1 => 1514736000
	 * $assign_time (str) [指定时间] 2018-1-1
	 * return (int) [时间戳] 1514736000
	 */
	public static function DEL_timeToTimestamp( $assign_time ){
	    return strtotime( date('Y-m-d', strtotime( $assign_time )) );
	}
	
	/**
	 * 指定时间格式的开始与结束转换时间戳
	 * 1970-1-1 => 1111
	 * @param int $starttime [必选] 开始时间
	 * @param int $endtime   [可选] 结束时间
	 * return array ['starttime'=>111, 'endtime'=>111]
	 */
	public static function DEL_timeStartAndEnd($starttime, $endtime){
	    $time_info = [];
	    $time_info['starttime'] = strtotime( $starttime );
	    $time_info['endtime'] = self::getSpecificTimestamp( 'today', strtotime($endtime) )['endtime'];
	    return $time_info;
	}
	
	/**
	 * 指定天格式->取开始与结束时间戳
	 * 支持指定天的任何时间
	 * @param int $assign_day [必选] 指定时间 [1970-1-1]
	 * return array ['starttime'=>1519660800, 'endtime'=>1519747199]
	 */
	public static function DEL_assignDayGetTimestamp( $assign_day ){
	    $time_info = [];
	    $time_info['starttime'] = strtotime( date('Y-m-d', strtotime( $assign_day )) );
	    $time_info['endtime'] = $time_info['starttime'] + 86399;  //指定天的结束时间
	    return $time_info;
	}
	
	/**
	 * 生成指定日期的那个月的开始与结束时间戳
	 * @param str $assign_day [1970-1-1]
	 */
	public static function DEL_assignMonthTimestamp($assign_day){
	    $time_info['starttime'] = strtotime( date('Y-m-d', strtotime( $assign_day )) );
	    $time_info['endtime'] = (int)mktime(23,59,59,date("m", $time_info['starttime']),date("t", $time_info['starttime']),date("Y", $time_info['starttime']));//本月结束时间戳
	    return $time_info;
	}
	
	/**
	 * 获得两个时间之间的天数与每天的时间开始和结束(时间戳)
	 * @param $starttime 开始时间
	 * @param $endtime   结束时间
	 * @param array $param [
	 *     'last_day' [可选] => 1 如果这个值存在即不要结束时间的那天
	 * ]
	 * @return array[
	 *     ['starttime' => 123, 'endtime' => 234],
	 *     ['starttime' => 123, 'endtime' => 234],
	 * ]
	 */
	public static function DEL_starttimeAndEndtimeGroup( $starttime, $endtime, $param = [] ){
	    // 
	    $day_num = 0;
	    $starttime = self::assignDayGetTimestamp(date('Y-m-d', $starttime))['starttime'];
	    $endtime   = self::assignDayGetTimestamp(date('Y-m-d', $endtime))['endtime'];
	    // 两个时间相差的秒数->准备转换成天数
	    $second_gap = $endtime - $starttime;
	    // 转换成天数->两个时间之间有多少天
	    $day_num = (int)($second_gap/(3600*24));
	    if( $day_num === 0 ) return 0;
	    if( !empty($param['last_day']) ){
	        $day_num = $day_num -1;
	    }
	    $day_info = [];
	    for ( $i = 0; $i <= $day_num; $i++ ){
	        $day_info[$i]['starttime'] = $starttime + ($i * self::$second_day2);
	        $day_info[$i]['endtime']   = $starttime + self::$second_day + ($i * self::$second_day2);
	    }
	    return $day_info;
	}
	
	/**
	 * 取今天剩作的秒数
	 * @return number
	 */
	public static function getTodayResidueSecond(){
	    $time_today_info = self::getSpecificTimestamp(self::$specificTime_Today);
	    $time_new         = time();
	    return $time_today_info['endtime'] - $time_new;
	}

	/**
	 * 计算时间相差的年数
	 * @param string $mydate 日期(格式：2000-1-1)
	 * @return int
	 */
	public static function differTimeOfYear( $oldDate, $newDate = null ){
		$newTime = $newDate === null ? self::getTime() : strtotime( $newDate );
		if( $newTime <= 0 ){
			throw com\Lib\Err\Exception::makeOfNew( '时间转换失败', com\Lib\Err\Code::$sysDataError );
		}
		//
		$birth = $oldDate;
		list( $by, $bm, $bd ) = explode( '-', $birth );
		$cm = date( 'n', $newTime );
		$cd = date( 'j', $newTime );
		$age = date( 'Y', $newTime ) - $by - 1;
		if ( $cm > $bm || $cm == $bm && $cd > $bd ) $age++;
		return $age;
	}
	

}
